// C风格的不定参宏函数
// gcc -o logger_1 logger_1.c
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

// v2:不定参宏函数
#define LOG(fmt, ...) printf("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__)

// C语言中不定参数据的访问
// 不定参数是同类型的
void printNum(int cnt, ...)
{
    // cnt表示其后有多少个参数
    va_list ap;
    va_start(ap, cnt); // 获取指定参数的起始地址, 这里是获取cnt参数之后的第一个参数的起始地址
    for (int i = 0; i < cnt; i++)
    {
        int num = va_arg(ap, int);
        printf("param[%d]:%d ", i, num);
    }
    va_end(ap); // 将ap指针置空
    printf("\n");
}

/*vasprintf(char **str, const char *format, va_list ap);
通过可变参数创建一个格式化的字符串, 并将其存储在动态分配的内存中;
str: 指向指针变量的指针, 用于存储格式化字符串的结果
format: 格式化字符串的格式, 与printf函数中的用法相同
ap: 指向va_start和va_arg函数处理的可变参数列表的指针
*/
// 不定参数是不同类型
void printArg(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    char *res;
    int ret = vasprintf(&res, fmt, ap);
    if(ret!=-1){
        printf(res);
        free(res);//一定要记得释放动态分配的内存
    }
    return ;
}
int main()
{
    // v0:普通打印输出
    //  printf("%s-%d\n","日志系统",123);
    // v1:显示打印的位置(文件+行号)
    //__FILE__: 文件
    //__LINE__: 行号
    // printf("[%s:%d] %s-%d\n", __FILE__, __LINE__, "日志系统", 123);
    // v2:不定参宏函数
    // LOG("%s-%d\n", "异步日志系统", 888);
    // LOG("日志系统\n");
    // printNum(2, 101, 202);
    // printNum(4, 9, 8, 7, 6);
    printArg("%s-%d-%c\n","hello",789,'y');
    printArg("log001\n");
    return 0;
}